﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SegIdenPC.Entidad;
using GS1.Utilitario;
using log4net;
using SegIdenPC.Herramientas;

namespace SegIdenPC.Formularios
{
    public partial class frmCompraLocal : Form
    {
        #region --- Variables y Propiedades ---
        private static readonly ILog log = LogManager.GetLogger(typeof(frmCompraLocal));

        private const string TITULO = "Generar Compra Local";

        private const string FORMATO_PRODUCTO_DESCRIPCION_DETALLADA = "{0} - {1} - {2} - {3}";

        private Proveedor proveedorActual = null;

        private Tienda tiendaSolicitante = null;
        private Producto producto = null;
        private ListaMoneda monedas = null;
        #endregion

        #region --- Constructor ---
        public frmCompraLocal()
        {
            InitializeComponent();
        }
        #endregion

        #region --- Eventos Formulario ---
        private void frmCompraLocal_Load(object sender, EventArgs e)
        {
            cargarFormulario();
        }

        private void tbtnNuevo_Click(object sender, EventArgs e)
        {
            nuevo();
        }

        private void tbtnGrabar_Click(object sender, EventArgs e)
        {
            grabar();
        }

        private void tbtnSalir_Click(object sender, EventArgs e)
        {
            salir();
        }

        private void btnBuscarProveedor_Click(object sender, EventArgs e)
        {
            elegirProveedor();
        }

        private void btnBuscarProducto_Click(object sender, EventArgs e)
        {
            elegirProducto();
        }

        private void btnBuscarSolicitante_Click(object sender, EventArgs e)
        {
            elegirSolicitante();
        }

        private void btnAgregar_Click(object sender, EventArgs e)
        {
            agregarProducto();
        }

        private void btnEliminar_Click(object sender, EventArgs e)
        {
            quitarProducto();
        }

        private void txtPrecio_KeyPress(object sender, KeyPressEventArgs e)
        {
            Libreria.SoloNumeros((TextBox)sender, e);
        }

        private void txtCantidad_KeyPress(object sender, KeyPressEventArgs e)
        {
            Libreria.SoloNumeros((TextBox)sender, e);
        }

        private void txtProveedorIdentificacion_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter) { buscarProveedor(); }
        }

        private void txtProveedorIdentificacion_TextChanged(object sender, EventArgs e)
        {
            limpiarDatosProveedor();
        }
        #endregion

        #region --- Metodos Propios ---

        private void cargarMonedas()
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            // Estableciendo operacion a ser enviada al Servicio REST
            operacion = new Operacion();
            operacion.numero = Constantes.OPERACION_LISTAR_MONEDAS;

            // Instanciando y ejecutando llamada al ServicioREST
            ConexionREST conexionREST = new ConexionREST();
            contenidoXML = conexionREST.ejecutarOperacion(operacion);

            // Obteniendo Objeto de Error
            OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

            // Validar si hay error
            if (operacionError != null)
            {
                Libreria.ShowMessageboxError(operacionError.descripcion);
                return;
            }

            // Obteniendo Objeto de ListaMoneda (Monedas)
            this.monedas = contenidoXML.DeserializarTo<ListaMoneda>();

            // Estableciendo listado de paises
            this.cboMoneda.DataSource = this.monedas.lista;
            this.cboMoneda.ValueMember = "codMoneda";
            this.cboMoneda.DisplayMember = "desMoneda";
            this.cboMoneda.SelectedIndex = 0;
        }

        private void cargarFormulario()
        {
            //ListaGeneral listaMoneda = null;
            cargarMonedas();
            try
            {
                //// Instanciando y creando listado de monedas
                //listaMoneda = new ListaGeneral();
                //listaMoneda.Add(new General { codigo = Constantes.CODIGO_MONEDA_SOLES, descripcion = Constantes.DESCRIPCION_MONEDA_SOLES });
                //listaMoneda.Add(new General { codigo = Constantes.CODIGO_MONEDA_DOLARES, descripcion = Constantes.DESCRIPCION_MONEDA_DOLARES });

                //// Estableciendo parametros del Combo Moneda
                //this.cboMoneda.DataSource = listaMoneda;
                //this.cboMoneda.ValueMember = Constantes.GENERAL_CODIGO;
                //this.cboMoneda.DisplayMember = Constantes.GENERAL_DESCRIPCION;
                //this.cboMoneda.SelectedIndex = 0;

                this.cboMoneda.Focus();

            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
        }

        private void elegirProveedor()
        {
            using (frmMantProveedor frmMantProveedor = new frmMantProveedor())
            {
                frmMantProveedor.formularioBusqueda = true;
                if (frmMantProveedor.ShowDialog() == DialogResult.Cancel) { return; }

                if (frmMantProveedor.proveedorActual.tipo.Equals(Constantes.DESCRIPCION_TIPO_PROVEEDOR_NACIONAL))
                {
                    this.proveedorActual = frmMantProveedor.proveedorActual;
                    this.txtProveedorIdentificacion.Text = this.proveedorActual.identificacion;
                    this.txtProveedorRazonSocial.Text = this.proveedorActual.razonSocial;
                    this.txtProveedorOrigen.Text = this.proveedorActual.tipo;
                }
                else
                {
                    Libreria.ShowMessageboxExclamacion("El proveedor no es valido para OC Local", TITULO);
                    this.btnBuscarProveedor.Focus();
                    return;
                }
            }
        }

        private void elegirProducto()
        {
            if (this.proveedorActual == null)
            {
                Libreria.ShowMessageboxExclamacion("Primero debe seleccionar el proveedor", TITULO);
                this.btnBuscarProveedor.Focus();
                return;
            }

            using (frmMantProducto frmMantProducto = new frmMantProducto())
            {
                frmMantProducto.formularioBusqueda = true;
                if (frmMantProducto.ShowDialog() == DialogResult.Cancel) { return; }

                if (frmMantProducto.productoActual.proveedor.codProveedor.Equals(this.proveedorActual.codProveedor))
                {
                    this.producto = frmMantProducto.productoActual;

                    // Mostrar los datos del producto
                    this.txtProductoCodigo.Text = producto.codigo;
                    this.txtProductoDescripcion.Text = string.Format(FORMATO_PRODUCTO_DESCRIPCION_DETALLADA, producto.nivelProducto.descripcion,
                                                                                                             producto.nivelTipo.descripcion,
                                                                                                             producto.nivelMaterial.descripcion,
                                                                                                             producto.nivelColor.descripcion);
                }
                else
                {
                    Libreria.ShowMessageboxExclamacion("El producto no es válido para el proveedor actual", TITULO);
                    this.btnBuscarProducto.Focus();
                    return;
                }
            }
        }

        private void elegirSolicitante()
        {
            using (frmMantTienda frmMantTienda = new frmMantTienda())
            {
                frmMantTienda.formularioBusqueda = true;
                if (frmMantTienda.ShowDialog() == DialogResult.Cancel) { return; }

                this.tiendaSolicitante = frmMantTienda.tiendaActual;
                this.txtSolicitante.Text = this.tiendaSolicitante.nombre;
            }
        }

        private bool validarEntradaBusqueda()
        {
            this.txtProveedorIdentificacion.Text = this.txtProveedorIdentificacion.Text.Trim();

            if (this.txtProveedorIdentificacion.Text.Equals(string.Empty))
            {
                Libreria.CampoNecesario(this.txtProveedorIdentificacion, "Debes ingresa el número de identificación", TITULO);
                return true;
            }

            if (this.txtProveedorIdentificacion.TextLength < 3)
            {
                Libreria.CampoNecesario(this.txtProveedorIdentificacion, "Debe ingresar por lo menos 3 caracteres para realizar la busqueda", TITULO);
                return true;
            }

            return false;
        }

        private void buscarProveedor()
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            try
            {
                if (validarEntradaBusqueda()) { return; }

                Cursor.Current = Cursors.WaitCursor;

                // Estableciendo operacion a ser enviada al Servicio REST
                operacion = new Operacion();
                operacion.numero = Constantes.OPERACION_OBTENER_PROVEEDOR_PORIDENTIFICACION;

                operacion.proveedor = new Proveedor();
                operacion.proveedor.identificacion = this.txtProveedorIdentificacion.Text;

                // Instanciando y ejecutando llamada al ServicioREST
                ConexionREST conexionREST = new ConexionREST();
                contenidoXML = conexionREST.ejecutarOperacion(operacion);

                // Obteniendo Objeto de Error
                OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

                // Validar si hay error
                if (operacionError != null)
                {
                    Libreria.ShowMessageboxError(operacionError.descripcion);
                    return;
                }

                // Obteniendo Objeto de Proveedor
                Proveedor proveedor = contenidoXML.DeserializarTo<Proveedor>();

                // Limpiando datos del proveedor anterior
                limpiarDatosProveedor();

                // Si el cliente existe
                if (proveedor != null)
                {
                    if (proveedor.estado.Equals(Constantes.ESTADO_CODIGO_INACTIVO))
                    {
                        Libreria.ShowMessageboxExclamacion("Este proveedor se encuentra en estado inactivo", TITULO);
                        return;
                    }

                    // Establecer su razon social
                    this.proveedorActual = proveedor;
                    this.txtProveedorRazonSocial.Text = this.proveedorActual.razonSocial;
                    this.txtProveedorOrigen.Text = this.proveedorActual.tipo.Equals(Constantes.CODIGO_TIPO_PROVEEDOR_NACIONAL) ?
                                                                                                        Constantes.DESCRIPCION_TIPO_PROVEEDOR_NACIONAL :
                                                                                                        Constantes.DESCRIPCION_TIPO_PROVEEDOR_EXTRANJERO;
                }
                else
                {
                    Libreria.ShowMessageboxExclamacion("El proveedor buscado no existe", TITULO);
                    return;
                }
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }

        private void limpiarDatosProveedor()
        {
            // Limpiando datos del proveedor anterior
            this.txtProveedorRazonSocial.Text = string.Empty;
            this.txtProveedorOrigen.Text = string.Empty;
        }

        private void nuevo()
        {
            // Activando grupo para modificar campos
            this.grpDatos.Enabled = true;
            this.tbtnGrabar.Enabled = true;

            // Limpiando los datos del formulario
            this.txtCodigo.Text = string.Empty;
            this.cboMoneda.SelectedIndex = 0;

            this.txtProveedorIdentificacion.Text = string.Empty;
            this.txtProveedorRazonSocial.Text = string.Empty;
            this.txtProveedorOrigen.Text = string.Empty;

            this.txtSolicitante.Text = string.Empty;
            this.txtProductoCodigo.Text = string.Empty;
            this.txtProductoDescripcion.Text = string.Empty;

            this.txtPrecio.Text = Constantes.VALOR_CERO_DECIMAL;
            this.txtCantidad.Text = Constantes.VALOR_CERO;

            // Limpiando grilla de detalle de la OC
            ListPersonalizada<LineaOrdenCompra> listaLineaOrdenCompra = (ListPersonalizada<LineaOrdenCompra>)this.dgvListado.DataSource;

            if (listaLineaOrdenCompra != null)
            {
                listaLineaOrdenCompra.Clear();

                this.dgvListado.DataSource = null;
                this.dgvListado.DataSource = listaLineaOrdenCompra;
            }

            // Estableciendo focus al combo moneda
            this.cboMoneda.Focus();
        }

        private void grabar()
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            try
            {
                if (validarEntrada()) { return; }

                // Solicitar confirmacion
                if (!Libreria.ShowMessageboxPregunta("¿Estas seguro de registrar la OC Local?", TITULO)) { return; }


                // Estableciendo operacion a ser enviada al Servicio REST
                operacion = new Operacion();
                operacion.numero = Constantes.OPERACION_REGISTRAR_ORDENCOMPRA;

                operacion.ordenCompra = new OrdenCompra();
                operacion.ordenCompra.codOC = Constantes.VALOR_CERO;

                operacion.ordenCompra.precioInternalFreight = Constantes.VALOR_CERO_DECIMAL;
                operacion.ordenCompra.moneda = new Moneda();
                operacion.ordenCompra.moneda.codigo = this.cboMoneda.SelectedValue.ToString();

                // Estableciendo proveedor del OC
                operacion.ordenCompra.proveedor = new Proveedor();
                operacion.ordenCompra.proveedor.codProveedor = this.proveedorActual.codProveedor;
                operacion.ordenCompra.proveedor.identificacion = this.proveedorActual.identificacion;
                operacion.ordenCompra.proveedor.razonSocial = this.proveedorActual.razonSocial;

                // Estableciendo usuario de regisro
                operacion.ordenCompra.usuario = new Usuario();
                operacion.ordenCompra.usuario.codUsuario = ParametrosAplicacion.USUARIO_ACTUAL.codUsuario;

                operacion.ordenCompra.estado = Constantes.ESTADO_OC_PENDIENTE;
                operacion.ordenCompra.origen = Constantes.CODIGO_ORIGEN_OC_NACIONAL;
                operacion.ordenCompra.fechaRegistro = DateTime.Now.ToString(Constantes.FORMATO_FECHAHORA);

                operacion.ordenCompra.listaLineaOrdenCompra = new ListaLineaOrdenCompra();
                operacion.ordenCompra.listaLineaOrdenCompra.lista = (ListPersonalizada<LineaOrdenCompra>)this.dgvListado.DataSource;

                // Instanciando y ejecutando llamada al ServicioREST
                ConexionREST conexionREST = new ConexionREST();
                contenidoXML = conexionREST.ejecutarOperacion(operacion);

                // Obteniendo Objeto de Error
                OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

                // Validar si hay error
                if (operacionError != null)
                {
                    Libreria.ShowMessageboxError(operacionError.descripcion);
                    return;
                }

                OperacionResultado operacionResultado = contenidoXML.DeserializarTo<OperacionResultado>();

                if ((operacionResultado != null) &&
                    (operacionResultado.esOK.Equals(Constantes.SI)))
                {
                    this.txtCodigo.Text = operacionResultado.codigoGenerado;
                    Libreria.ShowMessageboxInfo("Registro guardado correctamente", TITULO);
                }
                else
                {
                    Libreria.ShowMessageboxError("No se guardo los datos", TITULO);
                    return;
                }

                // Estableciendo los estados de los botones
                this.grpDatos.Enabled = false;
                this.tbtnGrabar.Enabled = false;
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
        }

        private bool validarEntrada()
        {
            bool resultado = false;

            this.txtProveedorRazonSocial.Text = this.txtProveedorRazonSocial.Text.Trim();

            if (this.cboMoneda.SelectedIndex == -1)
            {
                Libreria.CampoNecesario(this.cboMoneda, "Debe seleccionar una Moneda", TITULO);
                return true;
            }

            if (this.txtProveedorRazonSocial.Text.Equals(string.Empty))
            {
                Libreria.CampoNecesario(this.txtProveedorIdentificacion, "Debe elegir un Proveedor", TITULO);
                return true;
            }

            ListPersonalizada<LineaOrdenCompra> listaLineaOrdenCompra = (ListPersonalizada<LineaOrdenCompra>)this.dgvListado.DataSource;

            if ((listaLineaOrdenCompra == null) || (listaLineaOrdenCompra.Count == 0))
            {
                Libreria.CampoNecesario(this.dgvListado, "Debe ingresar por lo menos un producto a la Orden de Compra", TITULO);
                return true;
            }

            return resultado;
        }

        private bool validaEntradaProducto()
        {
            bool resultado = false;

            this.txtProductoCodigo.Text = this.txtProductoCodigo.Text.Trim();
            this.txtPrecio.Text = this.txtPrecio.Text.Trim();
            this.txtCantidad.Text = this.txtCantidad.Text.Trim();

            if (this.txtProductoCodigo.Text.Equals(string.Empty))
            {
                Libreria.CampoNecesario(this.txtProductoCodigo, "Debe elegir el producto solicitado", TITULO);
                return true;
            }

            if (this.txtPrecio.Text.Equals(string.Empty))
            {
                Libreria.CampoNecesario(this.txtPrecio, "Debe ingresar el campo precio del producto", TITULO);
                return true;
            }

            if (this.txtCantidad.Text.Equals(string.Empty))
            {
                Libreria.CampoNecesario(this.txtCantidad, "Debe ingresar el campo Cantidad del producto", TITULO);
                return true;
            }

            if ((this.txtCantidad.Text.EsEnteroConSigno()) &&
               (this.txtCantidad.Text.ToEntero() <= 0))
            {
                Libreria.CampoNecesario(this.txtCantidad, "Debe ingresar una Cantidad mayor a cero", TITULO);
                return true;
            }

            return resultado;
        }

        private void agregarProducto()
        {
            try
            {
                if (validaEntradaProducto()) { return; }

                if (validarProductoRepetido(this.producto.codigo))
                {
                    Libreria.CampoNecesario(this.txtProductoCodigo, "Este producto ya se encuentra asociado al Orden de Compra", TITULO);
                    return;
                }

                // Obteniendo lista de lineas
                ListPersonalizada<LineaOrdenCompra> listaLineaOrdenCompra = (ListPersonalizada<LineaOrdenCompra>)this.dgvListado.DataSource;
                if (listaLineaOrdenCompra == null) { listaLineaOrdenCompra = new ListPersonalizada<LineaOrdenCompra>(); }

                // Instanciando linea
                LineaOrdenCompra lineaOrdenCompra = new LineaOrdenCompra();

                // Estableciendo si es venta directa y el tipo de solicitante
                lineaOrdenCompra.ventaDirecta = Constantes.NO;

                if (this.tiendaSolicitante != null)
                {
                    lineaOrdenCompra.tienda = new Tienda();
                    lineaOrdenCompra.tienda.codigo = this.tiendaSolicitante.codigo;
                    lineaOrdenCompra.tienda.nombre = this.tiendaSolicitante.nombre;
                }

                // Estableciendo el producto
                lineaOrdenCompra.producto = new Producto();
                lineaOrdenCompra.producto.codigo = this.producto.codigo;
                lineaOrdenCompra.producto.descripcion = this.txtProductoDescripcion.Text;

                // Estableciendo el precio del producto
                lineaOrdenCompra.precioExworks = this.txtPrecio.Text;

                // Estableciendo la cantidad del producto
                lineaOrdenCompra.cantidad = this.txtCantidad.Text;
                lineaOrdenCompra.estado = Constantes.ESTADO_CODIGO_ACTIVO;

                // Agregando contacto
                listaLineaOrdenCompra.Add(lineaOrdenCompra);

                // Se establece propiedad para evitar que genere nuevas columnas que no estan mapeadas en la grilla
                this.dgvListado.AutoGenerateColumns = false;

                // Actualizando en grilla
                this.dgvListado.DataSource = null;
                this.dgvListado.DataSource = listaLineaOrdenCompra;

                formatearGrilla();
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
        }

        private void quitarProducto()
        {
            try
            {
                // Obteniendo lista de LineaOrdenCompra
                ListPersonalizada<LineaOrdenCompra> listaLineaOrdenCompra = (ListPersonalizada<LineaOrdenCompra>)this.dgvListado.DataSource;

                if (listaLineaOrdenCompra != null && listaLineaOrdenCompra.Count > 0)
                {
                    // Obteniedo la linea seleccionada
                    LineaOrdenCompra lineaOrdenCompra = listaLineaOrdenCompra[this.dgvListado.CurrentRow.Index];

                    // Eliminando linea de la OC
                    listaLineaOrdenCompra.Remove(lineaOrdenCompra);

                    // Se establece propiedad para evitar que genere nuevas columnas que no estan mapeadas en la grilla
                    this.dgvListado.AutoGenerateColumns = false;

                    // Actualizando en grilla
                    this.dgvListado.DataSource = null;
                    this.dgvListado.DataSource = listaLineaOrdenCompra;

                    //formatear grilla
                    formatearGrilla();
                }
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
        }

        private void formatearGrilla()
        {
            ListPersonalizada<LineaOrdenCompra> listaLineaOrdenCompra = null;
            listaLineaOrdenCompra = (ListPersonalizada<LineaOrdenCompra>)this.dgvListado.DataSource;

            if (listaLineaOrdenCompra != null)
            {
                for (int i = 0; i < listaLineaOrdenCompra.Count; i++)
                {
                    var lineaOrdenCompra = listaLineaOrdenCompra[i];

                    this.dgvListado.Rows[i].Cells[0].Value = lineaOrdenCompra.producto.codigo;
                    this.dgvListado.Rows[i].Cells[1].Value = lineaOrdenCompra.producto.codProductoProveedor;
                    this.dgvListado.Rows[i].Cells[2].Value = lineaOrdenCompra.producto.descripcion;
                }
            }
        }

        private bool validarProductoRepetido(string codProducto)
        {
            bool resultato = false;
            string codigoSolicitante = string.Empty;

            // Obteniendo lista de lineas
            ListPersonalizada<LineaOrdenCompra> listaLineaOrdenCompra = (ListPersonalizada<LineaOrdenCompra>)this.dgvListado.DataSource;

            if (listaLineaOrdenCompra != null)
            {
                foreach (LineaOrdenCompra item in listaLineaOrdenCompra)
                {
                    if (item.producto.codigo.Equals(codProducto))
                    {
                        resultato = true;
                        break;
                    }
                }
            }

            return resultato;
        }

        private void salir()
        {
            this.Close();
        }
        #endregion
    }
}
